/*
 * plat_uc.cpp
 *
 *  Created on: Aug 21, 2014
 *      Author: killerg
 */


#include "bill_deps.h"
#include "bill.h"
#include "bill_cfg.h"


#include <list>
#include <map>
#include <string>

static int serverId = 3395;
static int cpId = 40040;
static int gameId = 542195;
static const char* apiKey = "dc5b3d722b51f99aa6ec7ffd08a0f8ab";


//static void send_query(
//        http_server::p_request req,
//        int id,
//        int code,
//        const char* msg,
//        std::pair<std::string, std::string>* role = NULL) {
//
//    Json::Value ret;
//    ret["id"] = id;
//
//    ret["state"]["code"] = code;
//    ret["state"]["msg"] = msg;
//
//    Json::Value &rolelist = ret["rolelist"];
//    if (NULL != role) {
//        Json::Value ii_json;
//        ii_json["roleid"] = role->first;
//        ii_json["rolename"] = role->second;
//        rolelist.append(ii_json);
//    }
//
//    req->send_reply(200, to_cstr(ret));
//}

static void send_bill(http_server::p_request req, const char* why = NULL) {
	if (NULL == why) {
		req->send_reply(200, "SUCCESS");
	} else {
		req->send_reply(200, "FAILURE");
        char buff[100];
        time_t now = time(NULL);
        strftime(buff,100,"%Y%m%d_%H%M%S",localtime(&now));
    	UTIL_LOG(E, "%s EPI_uc msg:%s body:%s", buff, why, req->body.c_str());
	}
}

static void
_fake(http_server::p_request req) {
//	serverid 2
//	orderid uc-201408261837168367456
//	playerid 30
//	payfee 10
//	mc 359652057161502
    g_svrmgr->post_order(2, "uc-201408261837168367456", 30, 10, "359652057161502", [req](bool ok){
        if (ok)
        	send_bill(req);
        else
        	send_bill(req, "err post order");
    });
}

bool init_uc() {
    g_https->handle("/bill/uc", [](http_server::p_request req){
    	if (g_svrmgr->db_set >= 100) {
        	send_bill(req, "need retry");
        	return;
    	}
//
//    	_fake(req);
//    	return;

    	const Json::Value req_json = to_json(req->body);
        if (req->body.empty() || !req_json.isObject()) {
        	send_bill(req, "nobody");
            return;
        }

        const Json::Value &data_json = req_json["data"];
        if (!data_json.isObject()) {
        	send_bill(req, "invalid data");
            return;
        }

        string orderStatus =  data_json.get("orderStatus", "F").asCString();
        if (orderStatus != "S") {
            send_bill(req);
            return;
        }

        map<string, string> tosign;
        for (auto itr = data_json.begin(); itr != data_json.end(); ++itr) {
            string key = itr.key().asCString();
            if (key == "intfType") {
                if ((*itr).isInt()) {
                    tosign[key] = fmt_cstr("%d", (*itr).asInt());
                }
            } else {
                if ((*itr).isString())
                    tosign[key] = (*itr).asCString();
            }
        }

        stringstream ss;
        ss << cpId;
        for (const auto &p : tosign) {
            ss << p.first << "=" << p.second;
        }
        ss << apiKey;
        string calced_sign = Md5(ss.str().c_str());
        string sign = req_json.get("sign", "").asString();
        if (sign.empty() || calced_sign != sign) {
        	send_bill(req, "err sign");
            return;
        }

        int gameId = atoi(data_json.get("gameId", "-1").asCString());
        if (gameId < 0 || gameId != ::gameId) {
        	send_bill(req, "err gameId");
            return;
        }

        string account;
        string orderId;
        double payFee = 0;
        int serverid = -1;
        string machinecode;

        if (data_json["ucid"].isString()) {
            string ucid = data_json["ucid"].asCString();
            account = fmt_cstr("uc-%s", ucid.c_str());
        }
        if (data_json["orderId"].isString()) {
            orderId = fmt_cstr("uc-%s", data_json["orderId"].asCString());
        }
        if (data_json["amount"].isString()) {
            payFee = atof(data_json["amount"].asCString()) * g_cfg->Rate;
        }

        if (data_json["callbackInfo"].isString()) {
            std::vector<std::string> vNote;
            split(data_json["callbackInfo"].asString(), ",", vNote);
    		if (vNote.size() != 2) {
    			send_bill(req, "err callbackInfo");
                return;
    		}
    		serverid = atoi(vNote[0].c_str());
    		machinecode = vNote[1];
        }

        if (account.empty() || orderId.empty() || payFee <= 0 || serverid < 0) {
        	send_bill(req, "invalid arg");
            return;
        }

        auto playerinfo = g_svrmgr->get_player_info(serverid, account);
        if (NULL == playerinfo) {
        	send_bill(req, "no player info");
            return;
        }

        g_svrmgr->post_order(serverid, orderId, playerinfo->playerid, payFee, machinecode, [req](bool ok){
            if (ok)
            	send_bill(req);
            else
            	send_bill(req, "err post order");
        });

    });


    return true;
}
